diff options
Diffstat (limited to 'app/[lng]/partners/(partners)/settings/page.tsx')
| -rw-r--r-- | app/[lng]/partners/(partners)/settings/page.tsx | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/app/[lng]/partners/(partners)/settings/page.tsx b/app/[lng]/partners/(partners)/settings/page.tsx new file mode 100644 index 00000000..d831f0f4 --- /dev/null +++ b/app/[lng]/partners/(partners)/settings/page.tsx @@ -0,0 +1,224 @@ +// app/settings/page.tsx (인증 방식 기반 개선된 버전) +"use client" + +import { Separator } from "@/components/ui/separator" +import { AccountForm } from "@/components/settings/account-form" +import { SimpleReAuthModal } from "@/components/auth/simple-reauth-modal" +import { Skeleton } from "@/components/ui/skeleton" +import { Button } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { useSettingsAccess } from "@/hooks/use-settings-access" +import { Shield, User, Building, ArrowLeft, Mail, Key, Smartphone } from "lucide-react" +import { useRouter } from "next/navigation" +import React from "react" + +// 인증 방식별 아이콘과 라벨 +const authMethodConfig = { + otp: { icon: Smartphone, label: "OTP Authentication", color: "bg-blue-50 text-blue-700 border-blue-300" }, + email: { icon: Mail, label: "Email Authentication", color: "bg-gray-50 text-gray-700 border-gray-300" }, + sgips: { icon: Building, label: "S-Gips Enterprise", color: "bg-purple-50 text-purple-700 border-purple-300" }, + saml: { icon: Key, label: "SAML SSO", color: "bg-green-50 text-green-700 border-green-300" }, +} + +export default function SettingsAccountPage() { + const router = useRouter() + const { + accessType, + showReAuthModal, + isAuthenticated, + userEmail, + userId, + userDomain, + authMethod, + handleReAuthSuccess, + forceReAuth, + } = useSettingsAccess({ + validDuration: 5 * 60 * 1000, // 5분 + sgipsRedirectPath: "/partners/dashboard", + }) + + // 로딩 상태 + if (accessType === 'loading') { + return ( + <div className="space-y-6"> + <div> + <Skeleton className="h-7 w-24" /> + <Skeleton className="h-4 w-96 mt-2" /> + </div> + <Separator /> + <div className="space-y-4"> + <Skeleton className="h-10 w-full" /> + <Skeleton className="h-10 w-full" /> + <Skeleton className="h-10 w-full" /> + </div> + </div> + ) + } + + // 인증되지 않은 상태 + if (accessType === 'unauthenticated') { + return ( + <div className="text-center py-12"> + <div className="mx-auto h-12 w-12 rounded-full bg-red-100 flex items-center justify-center mb-4"> + <User className="h-6 w-6 text-red-600" /> + </div> + <h3 className="text-lg font-medium mb-2">Authentication Required</h3> + <p className="text-muted-foreground mb-4"> + Please sign in to access account settings. + </p> + <Button onClick={() => router.push("/auth/login")}> + Sign In + </Button> + </div> + ) + } + + // S-Gips 사용자 접근 차단 + if (accessType === 'blocked_sgips') { + return ( + <div className="text-center py-12"> + <div className="mx-auto h-12 w-12 rounded-full bg-purple-100 flex items-center justify-center mb-4"> + <Building className="h-6 w-6 text-purple-600" /> + </div> + <h3 className="text-lg font-medium mb-2">Enterprise Account</h3> + <p className="text-muted-foreground mb-2"> + Your account is managed through S-Gips enterprise system. + </p> + <p className="text-sm text-muted-foreground mb-4"> + Domain: <span className="font-medium">{userDomain}</span> + </p> + <Button + onClick={() => router.push("/dashboard")} + className="flex items-center gap-2" + > + <ArrowLeft className="h-4 w-4" /> + Back to Dashboard + </Button> + </div> + ) + } + + // 재인증 대기 상태 + if (accessType === 'reauth_required') { + return ( + <div className="space-y-6"> + <div> + <h3 className="text-lg font-medium">Account Settings</h3> + <p className="text-sm text-muted-foreground"> + Update your account settings and manage your profile information. + </p> + </div> + <Separator /> + + <div className="text-center py-12"> + <div className="mx-auto h-16 w-16 rounded-full bg-amber-100 flex items-center justify-center mb-4"> + <Shield className="h-8 w-8 text-amber-600 animate-pulse" /> + </div> + <h3 className="text-lg font-medium mb-2">Security Verification Required</h3> + <p className="text-muted-foreground mb-4"> + Please verify your password to access account settings. + </p> + + {/* 인증 방식 표시 */} + {authMethod && authMethodConfig[authMethod] && ( + <div className="flex items-center justify-center gap-2 mb-4"> + {React.createElement(authMethodConfig[authMethod].icon, { + className: "h-4 w-4 text-muted-foreground" + })} + <Badge variant="outline" className={authMethodConfig[authMethod].color}> + {authMethodConfig[authMethod].label} + </Badge> + </div> + )} + </div> + + <SimpleReAuthModal + isOpen={showReAuthModal} + onSuccess={handleReAuthSuccess} + userEmail={userEmail} + /> + </div> + ) + } + + // 접근 허용 상태 + const currentAuthConfig = authMethod && authMethodConfig[authMethod] + + return ( + <div className="space-y-6"> + <div> + <div className="flex items-center justify-between"> + <div> + <h3 className="text-lg font-medium">Account Settings</h3> + <p className="text-sm text-muted-foreground"> + Update your account settings and manage your profile information. + </p> + </div> + + {/* 보안 상태 표시 */} + <div className="flex items-center gap-2"> + <div className="flex items-center gap-2 px-3 py-1 bg-green-50 text-green-700 rounded-full text-sm"> + <Shield className="h-4 w-4" /> + <span>Verified</span> + </div> + </div> + </div> + + {/* 사용자 정보 및 인증 방식 표시 */} + <div className="mt-4 p-4 bg-slate-50 border border-slate-200 rounded-lg"> + <div className="flex items-center justify-between"> + <div className="space-y-2"> + <div className="flex items-center gap-3"> + <div className="flex items-center gap-2"> + <div className="h-2 w-2 bg-green-500 rounded-full"></div> + <span className="text-sm font-medium text-slate-900"> + {userEmail} + </span> + </div> + + {/* 인증 방식 뱃지 */} + {currentAuthConfig && ( + <div className="flex items-center gap-1"> + {React.createElement(currentAuthConfig.icon, { + className: "h-3 w-3" + })} + <Badge variant="outline" className={`text-xs ${currentAuthConfig.color}`}> + {currentAuthConfig.label} + {userDomain && authMethod === 'saml' && ` (${userDomain})`} + </Badge> + </div> + )} + </div> + + {/* 도메인 정보 */} + {userDomain && ( + <div className="text-xs text-slate-600"> + Domain: <span className="font-medium">{userDomain}</span> + </div> + )} + </div> + + <div className="flex items-center gap-2"> + {/* 이메일 인증 사용자만 재인증 버튼 표시 */} + {authMethod === 'email' && ( + <Button + variant="outline" + size="sm" + onClick={forceReAuth} + className="text-amber-700 border-amber-300 hover:bg-amber-50" + > + Re-verify + </Button> + )} + </div> + </div> + </div> + </div> + + <Separator /> + + {/* 메인 콘텐츠 */} + <AccountForm /> + </div> + ) +}
\ No newline at end of file |
